#pragma once
#include "base/function.hpp"
#include "base/mutex.h"
#include "base/config.h"
#include "net/buffer_reader.h"

#include <sys/uio.h>

namespace net_tools{
class Tcpserver;
class Tcpclient;
class Eventloop;

namespace base{
class Channel;
class Base_buffer;
class Memorypool;
} // namespace base

namespace net{
class Connect;

class Buffer{
friend class Connect;
friend class Connectpool;
friend class Buffer_reader;
friend class net_tools::Tcpserver;
friend class net_tools::Tcpclient;
 public:
  Buffer(net_tools::Eventloop* eventloop,Connect* connect);
  ~Buffer(){};
  void Init_channel(net_tools::base::Channel* channel);

  // Connect 接口 用户调用
  // buffer_reader
  Buffer_reader* Read();

  int Read(void* buf,uint32_t max_size);
  // 当套结字关闭的时候返回false 其余则true
  bool Write(void* buf,uint32_t len);
  // 零拷贝接口 未实现
  bool Write(net_tools::base::Base_buffer* base_buffer);
  // 用户接口
  void Close();
  // 用户接口
  void Close_right_now();
  // 用户接口 返回这个包有多大
  uint32_t Peak();

  void Append(void* buf,uint32_t len);

  void Send();

  // 被最顶层类设置 如TCPSERVER
  // 当可以供connect读时调用
  void Set_able_read_callback(connect_func cb);
  // 当套结字被关闭调用的
  void Set_able_close_callback(connect_func cb);
  // 当用户关闭套结字时
  void Set_able_user_close_callback(connect_func cb);

  void Send_heart_beat();

 private:
   // 创建一个预留的长度头
  void Creat_len_head();
  // 将长度设置进去
  void Set_len_head();

  // 修改write_index 满则换区
  void Recv(uint32_t len);
  void Clean_buffer();

  net_tools::base::Base_buffer* Get_new_buf(int size);
  // 查看head_recv_buf是否读完且换到正确的区
  void Read_buf_clear();
  // 从socket中读出 不修改index
  int Read_from_fd(iovec* iovector);
  int Write_in_fd();
  void Analyze_head();
  int Build_head(uint32_t len);

  // 清理 发送接收缓冲区
  //由epoll调用
  void Write_able_callback();
  //由epoll调用
  void Read_able_callback();
  //由epoll调用
  void Close_callback();
  void User_want_close();


  static net_tools::base::Memorypool* mempool_;
  net_tools::Eventloop*               eventloop_;
  Connect*                            connect_;
  net_tools::base::Channel*           channel_;
  int                                 fd_;

  connect_func read_callback_;
  connect_func close_callback_;
  connect_func user_want_close_callback_;

  // 只运行在单个线程 如果多线程则使用std::atmoic
  volatile bool send_all_;
  volatile bool user_want_close_;
  volatile bool still_have_;

  //剩余的长度 0为未收到新的包
  uint32_t recv_head_len_;
  uint32_t residue_len_;
  int      last_time_head_len_data_len_;

  //send_buf是最初的buf
  net_tools::base::Base_buffer* head_send_buf_;
  net_tools::base::Base_buffer* head_recv_buf_;
  net_tools::base::Base_buffer* now_send_buf_;
  net_tools::base::Base_buffer* now_recv_buf_;

  static __thread Buffer_reader* buffer_reader_;
};

} // namespace net
} // namespace net_tools